/*
Source : https://leetcode.com/problems/reverse-integer/
Author : nflush@outlook.com
Date   : 2016-05-18
*/

/*
65. Valid Number
Total Accepted: 45732 Total Submissions: 377590 Difficulty: Hard

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.

Subscribe to see which companies asked this question
*/

bool isNumber(char* s) {
    
}
class Solution {
        enum STATUS{
            START, // "   "
            MP,    // + , -
            NUM,   // 123456
            DNUM,  // .
            NUMD,  // 123.456
            NUME,  // 123e
            EMP,   // 123e+
            NUMED, // 1233e123
            ESP,   // "123e123   "
            FAIL,
        };
public:
    bool isNumber(string s) {
        STATUS stat_map[9][5] = {
            /* 0,   1,      2,      3,      4, */
           {START,  MP,     NUM,    FAIL,   DNUM},/* start */
           {FAIL,   FAIL,   NUM,    FAIL,   DNUM},/* mp */
           {ESP,    FAIL,   NUM,    NUME,   NUMD},/* num */
           {FAIL,   FAIL,   NUMD,   FAIL,   FAIL},/* dnum */
           {ESP,    FAIL,   NUMD,   NUME,   FAIL},/* numd */
           {FAIL,   EMP,    NUMED,  FAIL,   FAIL},/* nume */
           {FAIL,   FAIL,   NUMED,  FAIL,   FAIL},/* emp */
           {ESP,    FAIL,   NUMED,  FAIL,   FAIL},/* numed */
           {ESP,    FAIL,   FAIL,   FAIL,   FAIL}/* esp */
        };
        STATUS status = START;
        if (s.size() == 0){
            return false;
        }
        int type = 0;
        for (int i =0; i< s.size() && status != FAIL; i++){
            switch(s[i]){
            case ' ':
                type = 0;
                break;
            case '+':
            case '-':
                type = 1;
                break;
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                type = 2;
                break;
            case 'e':
                type = 3;
                break;
            case '.':
                type = 4;
                break;
            default:
                return false;
            }
            status = stat_map[status][type];
        }
        switch(status){
            case NUM: case NUMD: case NUMED: case ESP:
                return true;
        }
        return false;
    }
};


class Solution {
public:
    bool isNumber(string s) {
        bool point = false;
        bool hasE = false;
        int i = 0;
        //trim the space
        while(s[i] == ' ') i++;
        //check empty 
        if (s[i] == '\0' ) return false;
        //check sign
        if (s[i]=='+' || s[i]=='-') i++;

        int ihead  = i;
        for(; s[i]!='\0'; i++){
            // if meet point
            if ( s[i] == '.' ){
                if ( hasE == true || point == true){
                    return false;
                }
                if ( i == ihead && !isdigit(s[i+1])  ){
                    return false;
                }
                point = true; 
                continue; 
            }
            //if meet "e"
            if ( s[i] == 'e' ){
                if ( hasE == true || i == ihead) {
                    return false;
                }
                i++;
                if ( s[i]=='+' || s[i]=='-' )  i++;
                if ( !isdigit(s[i]) ) return false;

                hasE = true; 
                continue; 
            }
            //if meet space, check the rest chars are space or not
            if (s[i] == ' '){
                for (; s[i] != '\0'; i++){
                    if (s[i] != ' ') return false;
                }
                return true;
            }
            if ( !isdigit(s[i]) ) {
                return false;
            }

        }

        return true; 
    }
};

bool isNumber(string s)
{
    int n = s.size();
    if(n == 0) return false;

    int i = 0;
    //Skip leading spaces.
    while(s[i] == ' ') i++;

    //Significand
    if(s[i] == '+' || s[i] == '-') i++;

    int cnt = 0;
    //Integer part
    while(isdigit(s[i]))
    {
        i++;
        cnt++;
    }
    //Decimal point
    if(s[i] == '.') i++;
    //Fractional part
    while(isdigit(s[i]))
    {
        i++;
        cnt++;
    }
    if(cnt == 0) return false;  //No number in front or behind '.'

    //Exponential
    if(s[i] == 'e')
    {
        i++;
        if(s[i] == '+' || s[i] == '-') i++;
        if(!isdigit(s[i])) return false;    //No number follows
        while(isdigit(s[i])) i++;
    }

    //Skip following spaces;
    while(s[i] == ' ') i++;

    return s[i] == '\0';
}